#include "protreewidget.h"
#include<QDir>
#include"protreeitem.h"
#include"const.h"
#include<QHeaderView>
#include<QGuiApplication>
#include<QMenu>
#include<QFileDialog>
#include<QDebug>
#include<removeprodialog.h>
#include"slideshowdialog.h"

ProTreeWidget::ProTreeWidget(QWidget *parent):QTreeWidget(parent),
    _right_btn_item(nullptr), _active_item(nullptr), _selected_item(nullptr) ,_dialog_progress(nullptr),
    _thread_create_pro(nullptr), _thread_open_pro(nullptr)
{
    //    隐藏列头
    this->header()->hide();
    //    条目被鼠标触发事件
    connect(this, &QTreeWidget::itemPressed, this, &ProTreeWidget::SlotItemPressed);
    _action_import = new QAction(QIcon(":/icon/import.png"), tr("导入文件"), this);
    _action_setstart = new QAction(QIcon(":/icon/core.png"), tr("设置活动项目"), this);
    _action_closepro = new QAction(QIcon(":/icon/close.png"), tr("关闭项目"), this);
    _action_slideshow = new QAction(QIcon(":/icon/slideshow.png"), tr("轮播图播放"), this);

    connect(_action_import, &QAction::triggered, this, &ProTreeWidget::SlotImport);
    connect(_action_setstart, &QAction::triggered, this, &ProTreeWidget::SlotSetActive);
    connect(_action_closepro, &QAction::triggered, this, &ProTreeWidget::SlotClosePro);
    connect(this, &ProTreeWidget::itemDoubleClicked, this, &ProTreeWidget::SlotDoubleClickItem);
    connect(_action_slideshow, &QAction::triggered, this, &ProTreeWidget::SlotSlideShow);
    _player = std::make_shared<QMediaPlayer>(this);
    _playlist = std::make_shared<QMediaPlaylist>(this);
    _playlist->setPlaybackMode(QMediaPlaylist::Loop);
    _player->setPlaylist(_playlist.get());

}

void ProTreeWidget::AddProToTree(const QString name, const QString path)
{
    QDir dir(path);
    QString file_path = dir.absoluteFilePath(name);
    if(_set_path.find(file_path) != _set_path.end())
    {
        return ;
    }

    QDir pro_dir(file_path);
    if(!pro_dir.exists())
    {
        // mkpath 可以防止二级目录没创建的情况
        bool enable = pro_dir.mkpath(file_path);
        if(!enable)
        {
            return ;
        }
    }

    _set_path.insert(file_path);

    auto *item = new ProTreeItem(this, name, file_path, TreeItemPro);
    /*
     * DisplayRole:显示文本
     * DecorationRole：icon图标
     * ToolTipRole：鼠标悬浮时提示
    */
    //    项目条目是在数的第0级

    item->setData(0, Qt::DisplayRole, name);
    item->setData(0, Qt::DecorationRole, QIcon(":/icon/dir.png"));
    item->setData(0, Qt::ToolTipRole, file_path);
    this->addTopLevelItem(item);

}

void ProTreeWidget::SlotOpenPro(const QString path)
{
    if(_set_path.find(path) != _set_path.end())
    {
        return;
    }
    _set_path.insert(path);
    int file_count = 0;
    QDir pro_dir(path);
    const QString& proname = pro_dir.dirName();

    _thread_open_pro = std::make_shared<OpenTreeThread>(path, file_count, this);

    //    如果这里阻塞了，就会导致主线程的轮询卡顿，页面渲染也就会被卡住了，故耗时操作一般会开另一个线程处理
    _dialog_progress = new QProgressDialog(this);
//    todo:建议再创建一个新的Dialog来实现，不要复用了，后续不易维护；目前懒得改了就先用着
    connect(_thread_open_pro.get(), &OpenTreeThread::SigUpdateProgress, this, &ProTreeWidget::SlotUpdateProgress);
    connect(_thread_open_pro.get(), &OpenTreeThread::SigFinishProgress, this, &ProTreeWidget::SlotFinishProgress);
//    todo：取消事件就不写了，不给取消，哈哈哈 &QProgressDialog::canceled
    _thread_open_pro->start();
    _dialog_progress->setWindowTitle("Please wait...");
    _dialog_progress->setFixedWidth(PROGRESS_LENGTH);
    _dialog_progress->setRange(0, PROGRESS_MAX);
    _dialog_progress->exec();

}

void ProTreeWidget::SlotNextShow()
{
    if(!_selected_item)
    {
        return ;
    }
    auto *curItem = dynamic_cast<ProTreeItem*>(_selected_item)->GetNextItem();
    if(!curItem)
    {
        return;
    }
    emit SigUpdatePic(curItem->GetPath());
    _selected_item = curItem;
    this->setCurrentItem(curItem);
}

void ProTreeWidget::SlotPreShow()
{
    if(!_selected_item)
    {
        return ;
    }
    auto *curItem = dynamic_cast<ProTreeItem*>(_selected_item)->GetPreItem();
    if(!curItem)
    {
        return;
    }
    emit SigUpdatePic(curItem->GetPath());
    _selected_item = curItem;
    this->setCurrentItem(curItem);
}

void ProTreeWidget::SlotSetMusic(bool)
{
    QFileDialog file_dialog;
    file_dialog.setFileMode(QFileDialog::ExistingFiles);
    file_dialog.setWindowTitle("选择背景音乐");
    file_dialog.setDirectory(QDir::currentPath());
    file_dialog.setViewMode(QFileDialog::Detail);
    file_dialog.setNameFilter("(*.mp3)");
    QStringList fileNames;
    if (file_dialog.exec()){
         fileNames = file_dialog.selectedFiles();
    }
    if(fileNames.length() <= 0){
          return;
    }

    _playlist->clear();

    for(auto filename : fileNames)
    {
        _playlist->addMedia(QUrl::fromLocalFile(filename));
    }

    if(_player->state() != QMediaPlayer::PlayingState)
    {
        _playlist->setCurrentIndex(0);
    }
}

void ProTreeWidget::SlotStartMusic()
{
    _player->play();
}

void ProTreeWidget::SlotStopMusic()
{
    _player->pause();
}


void ProTreeWidget::SlotItemPressed(QTreeWidgetItem *pressedItem, int column)
{
//    如果按下的右键
    if(QGuiApplication::mouseButtons() == Qt::RightButton)
    {
        QMenu menu(this);
        int itemType = pressedItem->type();
        if(itemType == TreeItemPro)
        {
            _right_btn_item = pressedItem;
            menu.addAction(_action_import);
            menu.addAction(_action_setstart);
            menu.addAction(_action_closepro);
            menu.addAction(_action_slideshow);
//            设置菜单弹出来的地方是在鼠标的位置
            menu.exec(QCursor::pos());
        }
    }
}

void ProTreeWidget::SlotImport()
{
    QFileDialog file_dialog;
    file_dialog.setFileMode(QFileDialog::Directory);
    file_dialog.setWindowTitle("选择导入的文件夹");
    QString path = "";
    if(!_right_btn_item)
    {
        qDebug() << "_right_btn_item is empty";
        return ;
    }
    path = dynamic_cast<ProTreeItem*>(_right_btn_item)->GetPath();
    file_dialog.setDirectory(path);
    file_dialog.setViewMode(QFileDialog::Detail);

    QStringList fileNames;
    if(file_dialog.exec())
    {
        fileNames = file_dialog.selectedFiles();
    }

    if(fileNames.length() <= 0)
    {
        return ;
    }

    QString import_path = fileNames.at(0);
    int file_count = 0;
//    如果这里阻塞了，就会导致主线程的轮询卡顿，页面渲染也就会被卡住了，故耗时操作一般会开另一个线程处理
    _dialog_progress = new QProgressDialog(this);

    _thread_create_pro = std::make_shared<ProTreeThread>(std::ref(import_path), std::ref(path), _right_btn_item,
                                                    file_count, this, _right_btn_item, nullptr);
    connect(_thread_create_pro.get(), &ProTreeThread::SigUpdateProgress, this, &ProTreeWidget::SlotUpdateProgress);
    connect(_thread_create_pro.get(), &ProTreeThread::SigFinishProgress, this, &ProTreeWidget::SlotFinishProgress);
    connect(_dialog_progress, &QProgressDialog::canceled, this, &ProTreeWidget::SlotCancleProgress);
    connect(this, &ProTreeWidget::SigCancelProgress, _thread_create_pro.get(), &ProTreeThread::SlotCancleProgress);
    _thread_create_pro->start();

    _dialog_progress->setWindowTitle("Please wait...");
    _dialog_progress->setFixedWidth(PROGRESS_LENGTH);
    _dialog_progress->setRange(0, PROGRESS_MAX);
    _dialog_progress->exec();

}

void ProTreeWidget::SlotSetActive()
{
    if(!_right_btn_item)
    {
        return;
    }
    QFont nullFont;
    nullFont.setBold(false);
    if(_active_item)
    {
        _active_item->setFont(0, nullFont);
    }
    _active_item = _right_btn_item;
    nullFont.setBold(true);
    _active_item->setFont(0, nullFont);
}

void ProTreeWidget::SlotClosePro()
{
    RemoveProDialog remove_pro_dialog;
    auto res = remove_pro_dialog.exec();
    if(res != QDialog::Accepted)
    {
        return ;
    }
    bool b_remove = remove_pro_dialog.isRemoved();
    auto index_right_btn = this->indexOfTopLevelItem(_right_btn_item);
    auto *protreeitem = dynamic_cast<ProTreeItem*>(_right_btn_item);
    auto *selectitem = dynamic_cast<ProTreeItem*>(_selected_item);
    auto delete_path = protreeitem->GetPath();

    _set_path.remove(delete_path);
    if(b_remove)
    {
        QDir delete_dir(delete_path);
        delete_dir.removeRecursively();
    }

    if(protreeitem == _active_item)
    {
        _active_item = nullptr;
    }

//    如果当前打开的图片是处于要关闭的项目中
    if(selectitem && protreeitem == selectitem->GetRoot())
    {
        selectitem = nullptr;
        _selected_item = nullptr;
        emit SigClearSelected();
    }

    delete this->takeTopLevelItem(index_right_btn);
    _right_btn_item = nullptr;

}

void ProTreeWidget::SlotDoubleClickItem(QTreeWidgetItem *doubleItem, int column)
{
//    QGuiApplication 其实就是一个全局的属性
    if(QGuiApplication::mouseButtons() == Qt::LeftButton)
    {
        auto * tree_doubleItem = dynamic_cast<ProTreeItem*>(doubleItem);
        if(!tree_doubleItem)
        {
            return ;
        }
        int itemtype = tree_doubleItem->type();
        if(itemtype == TreeItemPic)
        {
            emit SigUpdateSelected(tree_doubleItem->GetPath());
            _selected_item = doubleItem;
        }
    }
}

void ProTreeWidget::SlotUpdateProgress(int count)
{
   if(!_dialog_progress)
   {
        return ;
   }
   if(count >= PROGRESS_MAX)
   {
        _dialog_progress->setValue(count % PROGRESS_MAX);
   }
   else
   {
        _dialog_progress->setValue(count);
   }
}

void ProTreeWidget::SlotFinishProgress()
{
    _dialog_progress->setValue(PROGRESS_MAX);
    _dialog_progress->deleteLater();
}

void ProTreeWidget::SlotCancleProgress()
{
    emit SigCancelProgress();
    delete _dialog_progress;
    _dialog_progress = nullptr;
}

void ProTreeWidget::SlotSlideShow()
{
    if(!_right_btn_item)
    {
        return ;
    }
    auto* right_pro_item = dynamic_cast<ProTreeItem*>(_right_btn_item);

    auto* last_child_item = right_pro_item->GetLastPicChild();
    if(!last_child_item)
    {
        return ;
    }

    auto* first_child_item = right_pro_item->GetFirPicChild();
    if(!first_child_item)
    {
        return ;
    }

    _slide_show_dialog = std::make_shared<SlideShowDialog>(this, first_child_item, last_child_item);
    _slide_show_dialog->setModal(true);
    _slide_show_dialog->showMaximized();
}
